home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Pascal Super Library
/
Pascal Super Library (CW International)(1997).bin
/
LIBRARY
/
CMPLTPAS
/
STICK.ASM
< prev
next >
Wrap
Assembly Source File
|
1988-08-01
|
6KB
|
147 lines
;======================================================================
;
; S T I C K - Assembly language joystick input for Turbo Pascal
;
;======================================================================
;
; by Jeff Duntemann 12 February 1988
; with thanks to Ted Mirecki for additional insights
;
; From: COMPLETE TURBO PASCAL 5.0 by Jeff Duntemann
; Scott, Foresman & Co., Inc. 1988 ISBN 0-673-38355-5
;
; STICK is written to be called from Turbo Pascal V4.0 using the
; {$L}/EXTERNAL procedure convention.
;
; Declare the procedure itself as an external using this declaration:
;
; {$L STICK}
; PROCEDURE STICK(StickNumber : Integer VAR X,Y : Integer);
; EXTERNAL;
;
; StickNumber specifies which joystick to read from, and the X and Y
; parameters return integers proportional to the joystick's position
; at the moment the stick is sampled. These integers will vary from
; stick to stick depending on the resistance of the potentiometers
; used within the stick, but will typically from from 3 to 150.
;
; The IBM standard game controller board consists of two pairs of
; one-shots, which output a pulse when triggered by an I/O write to
; I/O port $201. The length of this pulse is determined by an RC
; time constant circuit the resistance portion of which is the
; potentiometer in the joystick. As the handle is moved around, the
; two potentiometers (one for X, one for Y) run up and back, changing
; resistance as they go.
;
; To read one of the two joysticks, a dummy value (which may be anything
; at all) is written to I/O port $201. Port $201 must then be polled
; continuously, incrementing a register at each polling event. When
; the bit corresponding to that stick's X or Y coordinate changes state,
; the count in the register is returned as that coordinate value at the
; time the stick was sampled.
;
; Here is a map of the joystick bits as returned by port $201:
;
; |7 6 5 4 3 2 1 0|
; | | | |
; | | | - - - - - - -> X coordinate, joystick #1
; | | - - - - - - - -> Y coordinate, joystick #1
; | - - - - - - - - -> X coordinate, joystick #2
; - - - - - - - - - -> Y coordinate, joystick #2
;
; One thing to keep in mind is that a bit goes LOW when sampled, and
; you must test for a HIGH on that bit to indicate that the one-shot has
; timed out.
;
;
; To reassemble/relink STICK:
;-------------------------------------
; Assemble this file with MASM. "C>MASM STICK;"
;
;
; This structure defines the layout of parameters on the stack.
;
ONSTACK STRUC
OLDBP DW ? ;TOP OF STACK
RETADDR DD ? ;FAR RETURN ADDRESS
YADDR DD ? ;FAR ADDRESS OF X VALUE
XADDR DD ? ;FAR ADDRESS OF Y VALUE
STIK_NO DW ? ;STICK NUMBER
ONSTACK ENDS
CODE SEGMENT PUBLIC
ASSUME CS:CODE
PUBLIC STICK
; EQUATES FOR ONE-SHOT BITS FOR STICKS 1 & 2
STICK_X EQU 1
STICK_Y EQU 2
STICK PROC FAR
PUSH BP ;SAVE CALLER'S BP
MOV BP,SP ;STACK POINTER BECOMES NEW BP
PUSH DS
; GET THE X AXIS VALUE FIRST
MOV AH,STICK_X ; MOVE IN THE X TEST BIT
CMP [BP].STIK_NO,2 ; SEE IF WE'RE TESTING STICK #1 OR #2
JNE TEST_X
SHL AH,1 ; SHIFT BIT NUMBERS 2 LEFT FOR STICK #2
SHL AH,1
TEST_X: MOV AL,1 ; INITIALIZE OUTPUT VALUE
MOV DX,201H ; SET PORT ADDRESS
MOV BX,0 ; AND KEEPING THE RUNUP COUNT IN BX
MOV CX,BX ; LOOP 64K TIMES MAX
OUT DX,AL ; TRIGGER THE ONE-SHOTS
AGAIN_X: IN AL,DX ; READ THE ONE-SHOT BITS
TEST AL,AH ; TEST FOR A HIGH BIT 0
JE DELAY ; WE'RE DONE IF BIT 0 IS HIGH
INC BX ; OTHERWISE INCREMENT BX AND LOOP AGAIN
LOOP AGAIN_X
MOV BX,-1 ; SET X=-1 IF NO RESPONSE
; DELAY HERE TO LET THE OTHER THREE PULSES MAX OUT
DELAY: MOV CX,512
WAIT: LOOP WAIT
; NOW WE GET THE Y AXIS VALUE
MOV AH,STICK_Y ; MOVE IN THE Y TEST BIT
CMP [BP].STIK_NO,2 ; SEE IF WE'RE TESTING STICK #1 OR #2
JNE TEST_Y
SHL AH,1 ; SHIFT BIT NUMBERS 2 LEFT FOR STICK #2
SHL AH,1
TEST_Y: MOV SI,0 ; KEEP THE RUNUP COUNT FOR Y IN SI
MOV CX,SI ; SET LOOP LIMIT TO 64K
OUT DX,AL ; FIRE THE ONE-SHOTS AGAIN
AGAIN_Y: IN AL,DX ; READ THE ONE-SHOT BITS
TEST AL,AH ; TEST FOR A HIGH BIT 1
JE DONE ; WE'RE DONE IF BIT 1 IS HIGH
INC SI ; OTHERWISE INCREMENT SI AND LOOP AGAIN
LOOP AGAIN_Y
MOV SI,-1 ; SET Y=-1 IF NO RESPONSE
; MOVE RETURN VALUES FROM REGISTERS INTO VAR PARAMETERS X & Y
DONE: LDS DI,[BP].XADDR ;ADDR OF X INTO DS:DI
MOV [DI],BX ;X VALUE FROM BX TO DS:DI
LDS DI,[BP].YADDR ;DITTO FOR Y VALUE FROM SI
MOV [DI],SI
; IT'S OVER...NOW CLEAN UP THE STACK AND LEAVE
POP DS
MOV SP,BP ; CLEAN UP STACK AND LEAVE
POP BP ; RESTORE CALLER'S BP
RET 10
STICK ENDP
CODE ENDS
END